home *** CD-ROM | disk | FTP | other *** search
- /* noteoff.c -- this module keeps track of pending note offs for adagio */
-
- /*****************************************************************************
- * Change Log
- * Date | Change
- *-----------+-----------------------------------------------------------------
- * 31-Dec-85 | Created changelog
- * 31-Dec-85 | Add c:\ to include directives
- * 1-Jan-86 | Declare getmem char * for lint consistency
- * 21-Jan-86 | note_offs can now turn off more than one note per call
- *****************************************************************************/
-
- #include "cext.h"
- #include "stdio.h"
- #include "ctype.h"
- #include "adagio.h"
-
- /* off_type is a structure containing note-off information */
-
- typedef struct off_struct {
- long when;
- int voice;
- int pitch;
- struct off_struct *next;
- } *off_type;
-
- private off_type free_off; /* free list of off_type structures */
- private off_type off_events = NULL; /* active list */
- extern char * getmem();
-
- /****************************************************************************
- * Routines declared in this module
- ****************************************************************************/
-
- boolean note_offs();
- private off_type off_alloc();
- private void off_free();
- void off_init();
- void off_schedule();
-
- /****************************************************************************
- * note_offs
- * Inputs:
- * long time: the current time
- * Outputs:
- * return true if off list has more notes
- * Effect: turn off notes if it is time
- * Assumes:
- * Implementation:
- * Find scheduled note off events in off_events, compare with time
- ****************************************************************************/
-
- boolean note_offs(time)
- long time;
- {
- off_type temp;
- while (off_events != NULL && off_events->when <= time) {
- midi_note((off_events->voice) + 1, off_events->pitch, 0);
- temp = off_events;
- off_events = off_events->next;
- off_free(temp);
- }
- return (off_events != NULL);
- }
-
- /****************************************************************************
- * off_alloc
- * Outputs:
- * returns off_type: an allocated note off structure
- * Effect:
- * allocates a structure using getmem
- ****************************************************************************/
-
- private off_type off_alloc()
- {
- return (off_type) getmem(sizeof(struct off_struct));
- }
-
- /****************************************************************************
- * off_free
- * Inputs:
- * off_type off: a structure to deallocate
- * Effect:
- * returns off to freelist
- ****************************************************************************/
-
- private void off_free(off)
- off_type off;
- {
- off->next = free_off;
- free_off = off;
- }
-
- /****************************************************************************
- * off_init
- * Effect: initialize this module
- * Assumes:
- * only called once, otherwise storage is leaked
- ****************************************************************************/
-
- void off_init()
- {
- int i;
- for (i = 0; i < 50; i++) off_free(off_alloc());
- }
-
- /****************************************************************************
- * off_schedule
- * Inputs:
- * long offtime: time to turn note off
- * int voice: the midi channel
- * int pitch: the pitch
- * Effect:
- * schedules a note to be turned off
- * Assumes:
- * note_offs will be called frequently to actually turn off notes
- ****************************************************************************/
-
- void off_schedule(offtime, voice, pitch)
- long offtime;
- int voice, pitch;
- {
- off_type off, ptr, prv;
- /* allocate off */
- if ((off = free_off) == NULL) {
- off = off_alloc();
- } else free_off = off->next;
-
- if (off == NULL) {
- fprintf(stderr, "out of space for note off events");
- musicterm();
- exit(1);
- }
-
- off->when = offtime;
- off->voice = voice;
- off->pitch = pitch;
- /* insert into list of off events */
- ptr = off_events;
- if (ptr == NULL || offtime <= ptr->when) {
- off->next = ptr;
- off_events = off;
- } else {
- while (ptr != NULL && offtime > ptr->when) {
- prv = ptr;
- ptr = ptr->next;
- }
- prv->next = off;
- off->next = ptr;
- }
- /*
- * printf("off_schedule(%ld, %d, %d): \n", offtime, voice, pitch);
- * for (ptr = off_events; ptr != NULL; ptr = ptr->next) {
- * printf(" %ld: %d, %d\n", ptr->when, ptr->voice, ptr->pitch);
- * }
- */
- }